﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using ExpenseTracker.Entity;
using ExpenseTracker.Controller;

namespace ExpenseTracker
{    
    public partial class ExpenseReport : BaseForm
    {
        private ExpenseTracker.Controller.CategoryController _categoryController;
        private ExpenseTracker.Controller.ExpenseController _expenseController;
        private Dictionary<int, ExpenseTracker.Entity.Category> _categoryDictionary;

        public ExpenseReport(ExpenseTracker.Entity.Account account) : base(account)
        {
            _categoryController = new CategoryController(account);
            _expenseController = new ExpenseController(account);
            SetupCategoryDictionary();
            InitializeComponent();
        }

        protected override void OnLoad(EventArgs e)
        {
            SetupMonthCheckedListBox(true);
            SetupCategoryCheckedListBox(true);
            SetupExpenseList();
            PopulateExpenseList();
            base.OnLoad(e);
        }

        protected void SetupCategoryDictionary()
        {
            _categoryDictionary = new Dictionary<int, Category>();
            List<Category> list = _categoryController.GetCategories(TransactionType.Expense);
            foreach (Category item in list)
            {
                _categoryDictionary.Add(item.CategoryID, item);
            }
        }

        protected void SetupMonthCheckedListBox(bool preSelected)
        {
            QueryYear year = new QueryYear(Configuration.Instance.Year);
            foreach (QueryMonth month in year.Months)
            {
                clbMonth.Items.Add(month);
            }

            if (preSelected)
            {
                cbMonthToggle.Checked = true;
                cbMonthToggle_CheckedChanged(this, null);
            }
        }

        protected void SetupCategoryCheckedListBox(bool preSelected)
        {
            List<Category> categories = _categoryController.GetCategories(TransactionType.Expense);
            foreach (Category category in categories)
            {
                clbCategory.Items.Add(category);
            }

            if (preSelected)
            {
                cbCategoryToggle.Checked = true;
                cbCategoryToggle_CheckedChanged(this, null);
            }
        }

        protected void SetupExpenseList()
        {
            dgvExpense.AutoSizeColumnsMode = DataGridViewAutoSizeColumnsMode.Fill;
            dgvExpense.AutoSizeRowsMode = DataGridViewAutoSizeRowsMode.DisplayedCellsExceptHeaders;
            dgvExpense.ColumnHeadersBorderStyle = DataGridViewHeaderBorderStyle.Single;
            dgvExpense.CellBorderStyle = DataGridViewCellBorderStyle.Single;
            dgvExpense.GridColor = Color.Black;
            dgvExpense.RowHeadersVisible = false;

            dgvExpense.ColumnCount = 8;
            dgvExpense.Columns[0].Name = "Date";
            dgvExpense.Columns[1].Name = "Category";
            dgvExpense.Columns[2].Name = "Item";
            dgvExpense.Columns[3].Name = "Amount";
            dgvExpense.Columns[4].Name = "GST";
            dgvExpense.Columns[5].Name = "PST";
            dgvExpense.Columns[6].Name = "Total";
            dgvExpense.Columns[7].Name = "Disabled?";

            dgvExpense.SelectionMode = DataGridViewSelectionMode.FullRowSelect;
            dgvExpense.MultiSelect = false;
            dgvExpense.Dock = DockStyle.Fill;

            dgvExpense.CellDoubleClick += new DataGridViewCellEventHandler(dgvExpense_CellDoubleClick);
        }

        public void PopulateExpenseList()
        {
            List<QueryMonth> months = new List<QueryMonth>();
            for (int i = 0; i < clbMonth.CheckedItems.Count; i++)
            {
                QueryMonth item = clbMonth.CheckedItems[i] as QueryMonth;
                if (item != null)
                {
                    months.Add(item);
                }
            }

            List<Category> categories = new List<Category>();
            for (int i = 0; i < clbCategory.CheckedItems.Count; i++)
            {
                Category item = clbCategory.CheckedItems[i] as Category;
                if (item != null)
                {
                    categories.Add(item);
                }
            }

            dgvExpense.Rows.Clear();
            List<Expense> list = _expenseController.GetExpenses(months, categories, rbExcludeDisabled.Checked);

            int idx = 0;
            float amount = 0.0F;
            float gst = 0.0F;
            float pst = 0.0F;
            float total = 0.0F;
            string disabled = string.Empty;

            foreach (Expense item in list)
            {
                amount += item.Amount;
                gst += item.GST;
                pst += item.PST;
                total += item.Total;
                disabled = item.IsDisabled == true ? Boolean.TrueString : string.Empty;

                string[] row = { item.TransactionDate.ToShortDateString(), _categoryDictionary[item.CategoryID].Title, item.Item, item.Amount.ToString("N2"), item.GST.ToString("N2"), item.PST.ToString("N2"), item.Total.ToString("N2"), disabled };
                dgvExpense.Rows.Add(row);
                dgvExpense.Rows[idx++].Tag = item.ExpenseID;
            }

            Workspace parent = this.MdiParent as Workspace;
            if (parent != null)
            {
                StringBuilder sb = new StringBuilder();
                sb.Append("Expense Summary - ");
                sb.Append("Item: [" + list.Count + "] ; ");
                sb.Append("Amount: [" + amount.ToString("N2") + "] ; ");
                sb.Append("GST: [" + gst.ToString("N2") + "] ; ");
                sb.Append("PST: [" + pst.ToString("N2") + "] ; ");
                sb.Append("Total: [" + total.ToString("N2") + "]");
                parent.StatusLabel = sb.ToString();
            }
        }

        protected void dgvExpense_CellDoubleClick(object sender, EventArgs e)
        {
            if (dgvExpense.CurrentRow != null)
            {
                int expenseID = -1;
                if (int.TryParse(dgvExpense.CurrentRow.Tag.ToString(), out expenseID))
                {
                    ExpenseForm childForm = new ExpenseForm(Account);
                    childForm.Name = Guid.NewGuid().ToString();
                    childForm.MdiParent = this.MdiParent;
                    childForm.Text = "Update Expense";
                    childForm.FormAction = FormAction.Update;
                    childForm.Expense.ExpenseID = expenseID;
                    childForm.OnExpenseFormSaved += new ExpenseForm.ExpenseFormSaved(PopulateExpenseList);
                    childForm.Show();
                }
            }
        }

        private void cbMonthToggle_CheckedChanged(object sender, EventArgs e)
        {
            if (clbMonth.Items != null && clbMonth.Items.Count > 0)
            {
                for (int i = 0; i < clbMonth.Items.Count; i++)
                {
                    clbMonth.SetItemChecked(i, cbMonthToggle.Checked);
                }
            }
        }

        private void cbCategoryToggle_CheckedChanged(object sender, EventArgs e)
        {
            if (clbCategory.Items != null && clbCategory.Items.Count > 0)
            {
                for (int i = 0; i < clbCategory.Items.Count; i++)
                {
                    clbCategory.SetItemChecked(i, cbCategoryToggle.Checked);
                }
            }
        }

        private void btnSearch_Click(object sender, EventArgs e)
        {
            if (clbMonth.CheckedItems.Count > 0 && clbCategory.CheckedItems.Count > 0)
            {
                PopulateExpenseList();
            }
            else
            {
                MessageBox.Show("Please select at least one month and category.");
            }
        }

        private void ExpenseReport_FormClosing(object sender, FormClosingEventArgs e)
        {
            Workspace parent = this.MdiParent as Workspace;
            if (parent != null)
            {
                parent.StatusLabel = string.Empty;
            }
        }        
    }
}
